package it.polimi.reTravelDream.beans;

import it.polimi.reTravelDream.dto.ExcursionDTO;
import it.polimi.reTravelDream.dto.FlightDTO;
import it.polimi.reTravelDream.dto.HotelDTO;
import it.polimi.reTravelDream.dto.PrenotationDTO;
import it.polimi.reTravelDream.dto.TravelPackageDTO;
import it.polimi.reTravelDream.eao.ExcursionEAOLocal;
import it.polimi.reTravelDream.eao.FlightEAOLocal;
import it.polimi.reTravelDream.eao.HotelEAOLocal;
import it.polimi.reTravelDream.eao.PrenotationEAOLocal;
import it.polimi.reTravelDream.eao.TravelPackageActionEAOLocal;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.bean.SessionScoped;
import javax.faces.bean.ViewScoped;

@ManagedBean(name="searchPackages")
@ViewScoped
public class SearchPackages {
	
	@EJB
	private TravelPackageActionEAOLocal packageAction;
	
	@EJB
	private HotelEAOLocal hotelEAOLocal;
	
	@EJB
	private FlightEAOLocal flightEAOLocal;

	@EJB
	private ExcursionEAOLocal excursionEAOLocal;
	
	@EJB
	private PrenotationEAOLocal prenotationEAOLocal;
	
	private boolean isEdit;
	private boolean isItem;
	private boolean isAddItem;
	
	private Integer provaString;
	
	private List<TravelPackageDTO> result;
	
	private HashMap<Integer, FlightDTO> flightRelated;
	private HashMap<Integer, HotelDTO> hotelRelated;
	private HashMap<Integer, ExcursionDTO> excursionRelated;
	
	private HashMap<Integer, FlightDTO> possibleFLightToAdd;
	private HashMap<Integer, HotelDTO> possibleHotelToAdd;
	private HashMap<Integer, ExcursionDTO> possibleExcursionToAdd;
	
	private List<FlightDTO> flightDTOs;
	private List<HotelDTO> hotelDTOs;
	private List<ExcursionDTO> excursionDTOs;
	
	private List<FlightDTO> possibleFlightList;
	private List<HotelDTO> possibleHotelList;
	private List<ExcursionDTO> possibleExcursionList;
	
	
	private String errorRemoveFlight;
	private boolean isErrorFlight;
	
	private String errorRemoveHotel;
	private boolean isErrorHotel;
	
	private String errorRemoveExcursion;
	private boolean isErrorExcursion;
	
	
	private TravelPackageDTO selectedPackage;
	
	public SearchPackages() {
		this.possibleFlightList=new ArrayList<FlightDTO>();
		this.possibleHotelList=new ArrayList<HotelDTO>();
		this.possibleExcursionList=new ArrayList<ExcursionDTO>();
		
		this.result=new ArrayList<TravelPackageDTO>();
		
		this.isEdit=false;
		this.isItem=false;
		this.isAddItem=false;
		
		this.selectedPackage=new TravelPackageDTO();
		
		this.hotelRelated=new HashMap<Integer, HotelDTO>();
		this.flightRelated=new  HashMap<Integer, FlightDTO>();
		this.excursionRelated=new HashMap<Integer,ExcursionDTO>();
		
		this.possibleFLightToAdd=new HashMap<Integer,FlightDTO>();
		this.possibleHotelToAdd=new HashMap<Integer,HotelDTO>();
		this.possibleExcursionToAdd=new HashMap<Integer,ExcursionDTO>();
}
	@PostConstruct
	public void search(){
		List<TravelPackageDTO> temp= this.packageAction.getAllPackages();
		this.result=temp;

	}
	
	public void edit(TravelPackageDTO packageToEdit) {
		this.isEdit=true;
		this.selectedPackage=packageToEdit;
	}
	
	public void delete(TravelPackageDTO packageToDelete) {
		this.packageAction.removePackage(packageToDelete);
		this.search();
	}
	
	public void saveEdit(){
		this.packageAction.modifyPackage(this.selectedPackage);
		this.search();
		this.isEdit=false;
	}
	
	public void showItems(TravelPackageDTO packageSelected){
		this.isErrorFlight=false;

		this.isItem=true;
		this.selectedPackage=packageSelected;
		
		this.hotelDTOs=packageSelected.getPackageHotelDTOs();
		this.flightDTOs=packageSelected.getPackageFlights();
		this.excursionDTOs=packageSelected.getPackageExcursions();
		
		
		
		for(FlightDTO fDto:this.flightDTOs){
			this.flightRelated.put(fDto.getId(), fDto);
		}
		
		for (HotelDTO hDto:this.hotelDTOs){
			this.hotelRelated.put(hDto.getId(), hDto);
		}
		for (ExcursionDTO eDto:this.excursionDTOs){
			this.excursionRelated.put(eDto.getId(), eDto);
		}
		
		List<FlightDTO> allFlights=new ArrayList<FlightDTO>();
		List<FlightDTO> temp=flightEAOLocal.getAllFlights();
		for(FlightDTO f:temp){
			if (f.isActive()) {
				allFlights.add(f);
			}
		}
		
		for(FlightDTO fDto:allFlights){
			this.possibleFLightToAdd.put(fDto.getId(), fDto);
		}
		for(FlightDTO flightDTO:this.selectedPackage.getPackageFlights()){
			this.possibleFLightToAdd.remove(flightDTO.getId());
		}
		
		for(Integer integer: this.possibleFLightToAdd.keySet()){
			this.possibleFlightList.add(this.possibleFLightToAdd.get(integer));
		}
		
		List<HotelDTO> allHotel=new ArrayList<HotelDTO>();
		List<HotelDTO> temp2=hotelEAOLocal.getAllHotel();
		for(HotelDTO h:temp2){
			if (h.isActive()) {
				allHotel.add(h);
			}
		}
		
		for(HotelDTO hDto:allHotel){
			this.possibleHotelToAdd.put(hDto.getId(), hDto);
		}
		
		for(HotelDTO hotelDTO: this.selectedPackage.getPackageHotelDTOs()){
			this.possibleHotelToAdd.remove(hotelDTO.getId());
		}
		
		for(Integer integer1: this.possibleHotelToAdd.keySet()){
			this.possibleHotelList.add(this.possibleHotelToAdd.get(integer1));
		}
		
		List<ExcursionDTO> allExcursion=new ArrayList<ExcursionDTO>();
		List<ExcursionDTO> temp3=excursionEAOLocal.getAllExcursion();
		for(ExcursionDTO e:temp3){
			if (e.isActive()) {
				allExcursion.add(e);
			}
		}
		
		for(ExcursionDTO eDto:allExcursion){
			this.possibleExcursionToAdd.put(eDto.getId(), eDto);
		}
		
		for(ExcursionDTO excursionDTO: this.selectedPackage.getPackageExcursions()){
		this.possibleExcursionToAdd.remove(excursionDTO.getId());
		}
		
		for(Integer integer2: this.possibleExcursionToAdd.keySet()){
			this.possibleExcursionList.add(this.possibleExcursionToAdd.get(integer2));
		}
		
	}

	/**
	 * 
	 * remove Hotel
	 */
	
	public void removePackageHotel(HotelDTO hotelToRemove){
		this.isErrorFlight=false;
		this.isErrorHotel=false;
		this.isErrorExcursion=false;
		
		List<HotelDTO> hotelDTOs=this.selectedPackage.getPackageHotelDTOs();
		if(hotelDTOs.size()==1){
			this.errorRemoveHotel="A package must contain at least one hotel";
			this.isErrorHotel=true;
			return;
		}
		this.isErrorFlight=false;

		this.hotelRelated.remove(hotelToRemove.getId());
		
		this.hotelDTOs.clear();
		
		for(Integer i: this.hotelRelated.keySet()){
			this.hotelDTOs.add(this.hotelRelated.get(i));
		}
		
		this.possibleHotelToAdd.put(hotelToRemove.getId(),hotelToRemove);
		this.possibleHotelList.clear();
		
		
		for(Integer i:this.possibleHotelToAdd.keySet()){
			this.possibleHotelList.add(this.possibleHotelToAdd.get(i));
		}
		
		this.selectedPackage.setPackageHotelDTOs(this.hotelDTOs);
		this.packageAction.modifyPackage(this.selectedPackage);	
	}
	
	
	
	/**
	 * 
	 * remove Flight
	 */
	
	public void okError(){
		this.isErrorFlight=false;
		this.isErrorHotel=false;
		this.isErrorExcursion=false;
	}
	
	public void removePackageFlight(FlightDTO flightToRemove){
		this.isErrorFlight=false;
		this.isErrorHotel=false;
		this.isErrorExcursion=false;
		
		List<FlightDTO> pacakgeFlightDTOs=this.selectedPackage.getPackageFlights();
		if(pacakgeFlightDTOs.size()==2){
			this.errorRemoveFlight="a package must contain at least two flights!";
			this.isErrorFlight=true;
			return;
		}
		this.flightRelated.remove(flightToRemove.getId());
		
		this.flightDTOs.clear();
		
		for(Integer i: this.flightRelated.keySet()){
			this.flightDTOs.add(this.flightRelated.get(i));
		}
		
		this.possibleFLightToAdd.put(flightToRemove.getId(),flightToRemove);
		this.possibleFlightList.clear();
		
		
		for(Integer i:this.possibleFLightToAdd.keySet()){
			this.possibleFlightList.add(this.possibleFLightToAdd.get(i));
		}
		
		this.selectedPackage.setPackageFlights(this.flightDTOs);
		this.packageAction.modifyPackage(this.selectedPackage);
	}
	

	/**
	 * 
	 * Excursion
	 */
	
	
	public void removePackageExcursion(ExcursionDTO excursionToRemove){
		this.isErrorFlight=false;
		this.isErrorHotel=false;
		this.isErrorExcursion=false;
		
		List<ExcursionDTO> excursionDTOs=this.selectedPackage.getPackageExcursions();
		if (excursionDTOs.size()==1) {
			this.isErrorExcursion=true;
			this.errorRemoveExcursion="A package must contain at least one excursion";
			return;
		}
		this.excursionRelated.remove(excursionToRemove.getId());
		
		this.excursionDTOs.clear();
		
		for(Integer i: this.excursionRelated.keySet()){
			this.excursionDTOs.add(this.excursionRelated.get(i));
		}
		
		this.possibleExcursionToAdd.put(excursionToRemove.getId(),excursionToRemove);
		this.possibleExcursionList.clear();
		
		
		for(Integer i:this.possibleExcursionToAdd.keySet()){
			this.possibleExcursionList.add(this.possibleExcursionToAdd.get(i));
		}
		
		this.selectedPackage.setPackageExcursions(this.excursionDTOs);
		this.packageAction.modifyPackage(this.selectedPackage);	
		
	}
	
	
	public void addFlight(FlightDTO flightToAddToPackage){
		this.isErrorFlight=false;
		this.isErrorHotel=false;
		this.isErrorExcursion=false;

		this.flightRelated.put(flightToAddToPackage.getId(), flightToAddToPackage);
		
		this.flightDTOs.clear();

		for(Integer i: this.flightRelated.keySet()){
			this.flightDTOs.add(this.flightRelated.get(i));
		}

		
		this.possibleFLightToAdd.remove(flightToAddToPackage.getId());
		this.possibleFlightList.clear();
		
		
		for(Integer i:this.possibleFLightToAdd.keySet()){
			this.possibleFlightList.add(this.possibleFLightToAdd.get(i));
		}
		
		
		this.selectedPackage.setPackageFlights(this.flightDTOs);
		this.packageAction.modifyPackage(this.selectedPackage);

	}
	
	public void addHotel(HotelDTO hotelToAddToPackage){
		this.isErrorFlight=false;
		this.isErrorHotel=false;
		this.isErrorExcursion=false;
		this.hotelRelated.put(hotelToAddToPackage.getId(), hotelToAddToPackage);
		
		this.hotelDTOs.clear();

		for(Integer i: this.hotelRelated.keySet()){
			this.hotelDTOs.add(this.hotelRelated.get(i));
		}

		
		this.possibleHotelToAdd.remove(hotelToAddToPackage.getId());
		this.possibleHotelList.clear();
		
		
		for(Integer i:this.possibleHotelToAdd.keySet()){
			this.possibleHotelList.add(this.possibleHotelToAdd.get(i));
		}
		
		
		this.selectedPackage.setPackageHotelDTOs(this.hotelDTOs);
		this.packageAction.modifyPackage(this.selectedPackage);
		

	}
	
	public void addExcursion(ExcursionDTO excursionToAddToPackage){
		this.isErrorFlight=false;
		this.isErrorHotel=false;
		this.isErrorExcursion=false;
		
		this.excursionRelated.put(excursionToAddToPackage.getId(), excursionToAddToPackage);
		
		this.excursionDTOs.clear();

		for(Integer i: this.excursionRelated.keySet()){
			this.excursionDTOs.add(this.excursionRelated.get(i));
		}

		
		this.possibleExcursionToAdd.remove(excursionToAddToPackage.getId());
		this.possibleExcursionList.clear();
		
		
		for(Integer i:this.possibleHotelToAdd.keySet()){
			this.possibleExcursionList.add(this.possibleExcursionToAdd.get(i));
		}
		
		
		this.selectedPackage.setPackageExcursions(this.excursionDTOs);
		this.packageAction.modifyPackage(this.selectedPackage);
	

	}
	
	
	/**
	 * 
	 * 
	 * 
	 */
	
	public void cancel(){
		this.isEdit=false;
		this.isErrorFlight=false;
		this.isErrorHotel=false;
		this.isErrorExcursion=false;
	}
	
	
	/** getter and setter*/
	public List<TravelPackageDTO> getResult() {
		return result;
	}
	public void setResult(List<TravelPackageDTO> result) {
		this.result = result;
	}
	
	public boolean isEdit() {
		return isEdit;
	}
	public void setEdit(boolean isEdit) {
		this.isEdit = isEdit;
	}
	
	public TravelPackageDTO getSelectedPackage() {
		return selectedPackage;
	}
	public void setSelectedPackage(TravelPackageDTO selectedPackage) {
		this.selectedPackage = selectedPackage;
	}
	public boolean isItem() {
		return isItem;
	}
	public void setItem(boolean isItem) {
		this.isItem = isItem;
	}
	public List<FlightDTO> getFlightDTOs() {
		return flightDTOs;
	}
	public void setFlightDTOs(List<FlightDTO> flightDTOs) {
		this.flightDTOs = flightDTOs;
	}
	public List<HotelDTO> getHotelDTOs() {
		return hotelDTOs;
	}
	public void setHotelDTOs(List<HotelDTO> hotelDTOs) {
		this.hotelDTOs = hotelDTOs;
	}
	public String getProvaString() {
		return String.valueOf(provaString);
	}
	public void setProvaString(String provaString) {
		this.provaString = Integer.parseInt(provaString);
	}
	public boolean isAddItem() {
		return isAddItem;
	}
	public void setAddItem(boolean isAddItem) {
		this.isAddItem = isAddItem;
	}
	public HashMap<Integer, FlightDTO> getPossibleFLightToAdd() {
		return possibleFLightToAdd;
	}
	public void setPossibleFLightToAdd(HashMap<Integer, FlightDTO> possibleFLightToAdd) {
		this.possibleFLightToAdd = possibleFLightToAdd;
	}
	public HashMap<Integer, HotelDTO> getPossibleHotelToAdd() {
		return possibleHotelToAdd;
	}
	public void setPossibleHotelToAdd(HashMap<Integer, HotelDTO> possibleHotelToAdd) {
		this.possibleHotelToAdd = possibleHotelToAdd;
	}
	public List<FlightDTO> getPossibleFlightList() {
		return possibleFlightList;
	}
	public void setPossibleFlightList(List<FlightDTO> possibleFlightList) {
		this.possibleFlightList = possibleFlightList;
	}
	public List<HotelDTO> getPossibleHotelList() {
		return possibleHotelList;
	}
	public void setPossibleHotelList(List<HotelDTO> possibleHotelList) {
		this.possibleHotelList = possibleHotelList;
	}
	public HashMap<Integer, ExcursionDTO> getExcursionRelated() {
		return excursionRelated;
	}
	public void setExcursionRelated(HashMap<Integer, ExcursionDTO> excursionRelated) {
		this.excursionRelated = excursionRelated;
	}
	public HashMap<Integer, ExcursionDTO> getPossibleExcursionToAdd() {
		return possibleExcursionToAdd;
	}
	public void setPossibleExcursionToAdd(HashMap<Integer, ExcursionDTO> possibleExcursionToAdd) {
		this.possibleExcursionToAdd = possibleExcursionToAdd;
	}
	public List<ExcursionDTO> getExcursionDTOs() {
		return excursionDTOs;
	}
	public void setExcursionDTOs(List<ExcursionDTO> excursionDTOs) {
		this.excursionDTOs = excursionDTOs;
	}
	public List<ExcursionDTO> getPossibleExcursionList() {
		return possibleExcursionList;
	}
	public void setPossibleExcursionList(List<ExcursionDTO> possibleExcursionList) {
		this.possibleExcursionList = possibleExcursionList;
	}
	public String getErrorRemoveFlight() {
		return errorRemoveFlight;
	}
	public void setErrorRemoveFlight(String errorRemoveFlight) {
		this.errorRemoveFlight = errorRemoveFlight;
	}
	public boolean isErrorFlight() {
		return isErrorFlight;
	}
	public void setErrorFlight(boolean isErrorFlight) {
		this.isErrorFlight = isErrorFlight;
	}
	public String getErrorRemoveHotel() {
		return errorRemoveHotel;
	}
	public void setErrorRemoveHotel(String errorRemoveHotel) {
		this.errorRemoveHotel = errorRemoveHotel;
	}
	public boolean isErrorHotel() {
		return isErrorHotel;
	}
	public void setErrorHotel(boolean isErrorHotel) {
		this.isErrorHotel = isErrorHotel;
	}
	public String getErrorRemoveExcursion() {
		return errorRemoveExcursion;
	}
	public void setErrorRemoveExcursion(String errorRemoveExcursion) {
		this.errorRemoveExcursion = errorRemoveExcursion;
	}
	public boolean isErrorExcursion() {
		return isErrorExcursion;
	}
	public void setErrorExcursion(boolean isErrorExcursion) {
		this.isErrorExcursion = isErrorExcursion;
	}


	
}
